/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cip.esymons.tesoreria.bc;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TemporalType;
import org.cip.esymons.tesoreria.be.DetPagoAgrupado;
import org.cip.esymons.tesoreria.be.DocumentoPago;
import org.cip.esymons.tesoreria.be.EnumEstadoDocumentoPago;
import org.cip.esymons.tesoreria.be.TipoMoneda;
import org.cip.esymons.tramite.be.Documento;
import org.cip.esymons.tramite.be.TipoDocumento;
import oracle.toplink.essentials.config.HintValues;
import oracle.toplink.essentials.config.TopLinkQueryHints;
import org.cip.esymons.general.util.Utiles;

/**
 *
 * @author Administrador
 */
@Stateless
public class DocumentoPagoFacade implements DocumentoPagoFacadeLocal {

    @PersistenceContext
    private EntityManager em;

    public void create(DocumentoPago documentoPago) {
        try {
            Documento doc = (Documento) documentoPago;
            em.persist(doc);
        } catch (Exception ex) {
            System.out.println("Errorrrrrrrrrrrrrrrrrrrrrrrrrrr" + ex.getMessage());
        }
    }

    public void edit(DocumentoPago documentoPago) {
        em.merge(documentoPago);
    }

    public void remove(DocumentoPago documentoPago) {
        em.remove(em.merge(documentoPago));
    }

    public DocumentoPago find(Object id) {
        try {
            return em.find(DocumentoPago.class, id);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public List<DocumentoPago> findAll() {
        try {
            return em.createQuery("select object(o) from DocumentoPago as o").getResultList();
        } catch (Exception e) {
            return new ArrayList();
        }
    }

    @Override
    public List<DocumentoPago> buscarDocumentosDelDia(Date fecha) {
        try {
            return em.createQuery("select object(o) from DocumentoPago as o Where o.dpaFechPago between ?1 and ?2").setParameter(1, Utiles.fechaInicioDia(fecha),TemporalType.TIMESTAMP).setParameter(2, Utiles.fechaFinDia(fecha),TemporalType.TIMESTAMP).getResultList();
        } catch (Exception e) {
            return new ArrayList();
        }
    }

    @Override
    public DocumentoPago buscarDocumentosParaCobroPorPlanilla(Integer serie,Date fecha,TipoDocumento tipoDocumento) {
        try {
            StringBuilder sb = new StringBuilder();
            sb.append("select object(o) from DocumentoPago as o Where (o.dpaFechemision between ?1 and ?2)");
            sb.append(" and o.dpaSerie=?3");
            sb.append(" and o.fkTdoCodigo=?4");
            List<DocumentoPago> lista = em.createQuery(sb.toString()).setParameter(1, Utiles.fechaInicioDia(fecha),TemporalType.TIMESTAMP).setParameter(2, Utiles.fechaFinDia(fecha),TemporalType.TIMESTAMP).setParameter(3, serie.toString()).setParameter(4, tipoDocumento).getResultList();
            return lista.get(0);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public List<DetPagoAgrupado> buscarDetalleDocumento(Long codigo) {
        try {
            return em.createQuery("select o from DetPagoAgrupado as o Where o.docCodigo.docCodigo=?1").setParameter(1, codigo).setHint(TopLinkQueryHints.REFRESH, HintValues.TRUE).getResultList();
        } catch (Exception e) {
            return new ArrayList();
        }
    }

    @Override
    public List<DocumentoPago> busquedaDocumentos(Integer tipo, String nombre, String beneficiario, Date fecIniE, Date fecFinE,
            EnumEstadoDocumentoPago estado, String nroDoc, TipoMoneda tipoMoneda, TipoDocumento tipoDocumento, Date fecIniP, Date fecFinP, String cuenta) {
        try {
            //tipo=0->persona Natural;tipo=1->persona Juridica
            String[] criterios;
            StringBuilder sb = new StringBuilder();
            StringBuilder where = new StringBuilder();
            sb.append(" SELECT distinct ");
            sb.append(" tes_documento_pago.*,tra_documento_generado.*,tra_documento.* ");
            sb.append(" FROM ");
            sb.append(" `tra_documento_generado` tra_documento_generado INNER JOIN `tes_documento_pago` tes_documento_pago ON tra_documento_generado.`doc_codigo` = tes_documento_pago.`fk_doc_codigo` ");
            sb.append(" INNER JOIN `tra_documento` tra_documento ON tra_documento_generado.`doc_codigo` = tra_documento.`doc_codigo` ");            
            Integer cont = 0;
            if (tipo == null) {
                sb.append(" INNER JOIN `gen_solicitante` gen_solicitante ON tra_documento.`fk_sol_codigo` = gen_solicitante.`sol_codigo` ");
            } else {
                if (tipo == 0) {
                    if (nombre != null && !nombre.isEmpty()) {
                        String pat, mat, nom, dni, cip;
                        criterios = nombre.split(";");
                        pat = criterios[0].substring(1);
                        mat = criterios[1].substring(1);
                        nom = criterios[2].substring(1);
                        dni = criterios[3].substring(1);
                        cip = criterios[4].substring(1);
                        if (!dni.isEmpty() || !cip.isEmpty() || !pat.isEmpty() || !mat.isEmpty() || !nom.isEmpty()) {
                            sb.append(" INNER JOIN `gen_solicitante` gen_solicitante ON tra_documento.`fk_sol_codigo` = gen_solicitante.`sol_codigo` ");
                            sb.append(" INNER JOIN `gen_persona_natural` gen_persona_natural ON gen_solicitante.`sol_codigo` = gen_persona_natural.`per_codigo` ");
                        }
                        if (!dni.isEmpty() || !cip.isEmpty()) {
                            if (!dni.isEmpty()) {
                                where.append(" and gen_persona_natural.`per_nroDni` =?").append((++cont).toString());
                            }
                            if (!cip.isEmpty()) {
                                sb.append(" INNER JOIN `col_colegiado` col_colegiado ON gen_persona_natural.`per_codigo` = col_colegiado.`col_codigo` ");
                                where.append(" and col_colegiado.`col_numeroCip` =?").append((++cont).toString());
                            }
                        } else {
                            if (!pat.isEmpty()) {
                                where.append(" and gen_persona_natural.`per_apellidoPaterno` =?").append((++cont).toString());
                            }
                            if (!mat.isEmpty()) {
                                where.append(" and gen_persona_natural.`per_apellidoMaterno` =?").append((++cont).toString());
                            }
                            if (!nom.isEmpty()) {
                                where.append(" and gen_persona_natural.`per_nombres` like ?").append((++cont).toString());
                            }
                        }
                    }
                }

                if (tipo == 1) {
                    String raz, ruc;
                    criterios = nombre.split(";");
                    raz = criterios[0].substring(1);
                    ruc = criterios[1].substring(1);
                    if (!ruc.isEmpty() || !raz.isEmpty()) {
                        sb.append(" INNER JOIN `gen_solicitante` gen_solicitante ON tra_documento.`fk_sol_codigo` = gen_solicitante.`sol_codigo` ");
                        sb.append(" INNER JOIN `gen_persona_juridica` gen_persona_juridica ON gen_solicitante.`sol_codigo` = gen_persona_juridica.`emp_codigo` ");
                    }
                    if (!ruc.isEmpty()) {
                        where.append(" and gen_solicitante.`sol_ruc` =?").append((++cont).toString());
                    } else {
                        if (!raz.isEmpty()) {
                            where.append(" and gen_persona_juridica.`emp_razonSocial` like ?").append((++cont).toString());
                        }
                    }
                }
            }

            if (beneficiario != null && !beneficiario.isEmpty()) {
                String pat, mat, nom, dni, cip;
                criterios = beneficiario.split(";");
                pat = criterios[0].substring(1);
                mat = criterios[1].substring(1);
                nom = criterios[2].substring(1);
                dni = criterios[3].substring(1);
                cip = criterios[4].substring(1);
                if (!dni.isEmpty() || !cip.isEmpty() || !pat.isEmpty() || !mat.isEmpty() || !nom.isEmpty()) {
                    sb.append(" INNER JOIN `tes_beneficiario_x_pago` tes_beneficiario_x_pago ON tes_documento_pago.`fk_doc_codigo` = tes_beneficiario_x_pago.`fk_doc_codigodpa` ");
                    sb.append(" INNER JOIN `gen_persona_natural` gen_persona_naturalBe ON gen_persona_naturalBe.`per_codigo` = tes_beneficiario_x_pago.`fk_solcodigopna` ");
                }
                if (!dni.isEmpty() || !cip.isEmpty()) {
                    if (!dni.isEmpty()) {
                        where.append(" and gen_persona_naturalBe.`per_nroDni` =?").append((++cont).toString());
                    }
                    if (!cip.isEmpty()) {
                        sb.append(" INNER JOIN `col_colegiado` col_colegiado ON gen_persona_naturalBe.`per_codigo` = col_colegiado.`col_codigo` ");
                        where.append(" and col_colegiado.`col_numeroCip` =?").append((++cont).toString());
                    }
                } else {
                    if (!pat.isEmpty()) {
                        where.append(" and gen_persona_naturalBe.`per_apellidoPaterno` =?").append((++cont).toString());
                    }
                    if (!mat.isEmpty()) {
                        where.append(" and gen_persona_naturalBe.`per_apellidoMaterno` =?").append((++cont).toString());
                    }
                    if (!nom.isEmpty()) {
                        where.append(" and gen_persona_naturalBe.`per_nombres` like ?").append((++cont).toString());
                    }
                }
            }

            if (fecIniP != null && fecFinP != null) {
                where.append(" and (tes_documento_pago.`dpa_fechpago` between ?").append((++cont).toString());
                where.append(" and ?").append((++cont).toString()).append(") ");
            }

            if (fecIniE != null && fecFinE != null) {
                where.append(" and (tes_documento_pago.`dpa_fechemision` between ?").append((++cont).toString());
                where.append(" and ?").append((++cont).toString()).append(") ");
            }

            if (estado != null) {
                where.append(" and tes_documento_pago.`dpa_estado` =?").append((++cont).toString());
            }
            if (nroDoc != null && !nroDoc.isEmpty()) {
                String ini, fin = "";
                criterios = nroDoc.split("-");
                ini = criterios[0];
                if (criterios.length > 1) {
                    fin = criterios[1];
                }
                if (!ini.isEmpty() && !fin.isEmpty()) {
                    where.append(" and (tra_documento.`doc_numero` between ?").append((++cont).toString());
                    where.append(" and ?").append((++cont).toString()).append(" ) ");
                } else {
                    if (!ini.isEmpty()) {
                        where.append(" and tra_documento.`doc_numero` =?").append((++cont).toString());
                    }
                }
            }

            if (tipoMoneda != null) {
                where.append(" and tes_documento_pago.`tmo_codigo` =?").append((++cont).toString());
            }
            if (tipoDocumento != null) {
                where.append(" and tra_documento.`fk_tdo_codigo` =?").append((++cont).toString());
            }

            if (cuenta != null && !cuenta.isEmpty()) {
                sb.append(" INNER JOIN `tes_det_pagagrupado` tes_det_pagagrupado ON tes_documento_pago.`fk_doc_codigo` = tes_det_pagagrupado.`doc_codigo` ");
                where.append(" and tes_det_pagagrupado.`cin_codigo`=?").append((++cont).toString());
            }

            if (!where.toString().isEmpty()) {
                cont = 0;
                sb.append(" Where ").append(where.toString().substring(4));
                sb.append(" order by tra_documento.`fk_tdo_codigo` ");
                Query q = em.createNativeQuery(sb.toString(), DocumentoPago.class);
                if (tipo != null) {
                    if (tipo == 0) {
                        if (nombre != null && !nombre.isEmpty()) {
                            String pat, mat, nom, dni, cip;
                            criterios = nombre.split(";");
                            pat = criterios[0].substring(1);
                            mat = criterios[1].substring(1);
                            nom = criterios[2].substring(1);
                            dni = criterios[3].substring(1);
                            cip = criterios[4].substring(1);
                            if (!dni.isEmpty() || !cip.isEmpty()) {
                                if (!dni.isEmpty()) {
                                    q.setParameter(++cont, dni);
                                }
                                if (!cip.isEmpty()) {
                                    q.setParameter(++cont, cip);
                                }
                            } else {
                                if (!pat.isEmpty()) {
                                    q.setParameter(++cont, pat);
                                }
                                if (!mat.isEmpty()) {
                                    q.setParameter(++cont, mat);
                                }
                                if (!nom.isEmpty()) {
                                    q.setParameter(++cont, "%" + nom + "%");
                                }
                            }
                        }
                    }

                    if (tipo == 1) {
                        String raz, ruc;
                        criterios = nombre.split(";");
                        raz = criterios[0].substring(1);
                        ruc = criterios[1].substring(1);
                        if (!ruc.isEmpty()) {
                            q.setParameter(++cont, ruc);
                        } else {
                            if (!raz.isEmpty()) {
                                q.setParameter(++cont, "%" + raz + "%");
                            }
                        }
                    }
                }

                if (beneficiario != null && !beneficiario.isEmpty()) {
                    String pat, mat, nom, dni, cip;
                    criterios = beneficiario.split(";");
                    pat = criterios[0].substring(1);
                    mat = criterios[1].substring(1);
                    nom = criterios[2].substring(1);
                    dni = criterios[3].substring(1);
                    cip = criterios[4].substring(1);
                    if (!dni.isEmpty() || !cip.isEmpty()) {
                        if (!dni.isEmpty()) {
                            q.setParameter(++cont, dni);
                        }
                        if (!cip.isEmpty()) {
                            q.setParameter(++cont, cip);
                        }
                    } else {
                        if (!pat.isEmpty()) {
                            q.setParameter(++cont, pat);
                        }
                        if (!mat.isEmpty()) {
                            q.setParameter(++cont, mat);
                        }
                        if (!nom.isEmpty()) {
                            q.setParameter(++cont, "%" + nom + "%");
                        }
                    }
                }

                if (fecIniP != null && fecFinP != null) {
                    q.setParameter(++cont, Utiles.fechaInicioDia(fecIniP), TemporalType.TIMESTAMP);
                    q.setParameter(++cont, Utiles.fechaFinDia(fecFinP), TemporalType.TIMESTAMP);
                }

                if (fecIniE != null && fecFinE != null) {
                    q.setParameter(++cont, Utiles.fechaInicioDia(fecIniE), TemporalType.TIMESTAMP);
                    q.setParameter(++cont, Utiles.fechaFinDia(fecFinE), TemporalType.TIMESTAMP);
                }

                if (estado != null) {
                    q.setParameter(++cont, estado.ordinal());
                }

                if (nroDoc != null && !nroDoc.isEmpty()) {
                    String ini, fin = "";
                    criterios = nroDoc.split("-");
                    ini = criterios[0];
                    if (criterios.length > 1) {
                        fin = criterios[1];
                    }
                    if (!ini.isEmpty() && !fin.isEmpty()) {
                        q.setParameter(++cont, ini);
                        q.setParameter(++cont, fin);
                    } else {
                        if (!ini.isEmpty()) {
                            q.setParameter(++cont, ini);
                        }
                    }

                }

                if (tipoMoneda != null) {
                    q.setParameter(++cont, tipoMoneda.getTmoCodigo());
                }
                if (tipoDocumento != null) {
                    q.setParameter(++cont, tipoDocumento.getTdoCodigo());
                }
                if (cuenta != null && !cuenta.isEmpty()) {
                    q.setParameter(++cont, cuenta);
                }

                List<DocumentoPago> listaResultante = new ArrayList<DocumentoPago>();                
                for (DocumentoPago dp : (List<DocumentoPago>) q.getResultList()) {
                    if(dp.getListaDetPagoAgrupados()==null || dp.getListaDetPagoAgrupados().size()<=0){
                        dp.setListaDetPagoAgrupados(buscarDetalleDocumento(dp.getDocCodigo()));
                    }
                    listaResultante.add(dp); 
                }
                return listaResultante;
            } else {
                return new ArrayList<DocumentoPago>();
            }
        } catch (Exception e) {
            return new ArrayList<DocumentoPago>();
        }
    }
}
